/*
 * @Author: 江舟 jijiangzhou@recycloud.cn
 * @Date: 2024-03-22 15:55:39
 * @LastEditors: 江舟 jijiangzhou@recycloud.cn
 * @LastEditTime: 2024-06-26 15:22:03
 * @FilePath: \vite-project\src\components\common\FileUploader.tsx
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import React from 'react';
import { Icon } from '@iconify/react/dist/iconify.js';
import { Spin, type UploadProps, Upload, UploadFile, Modal, App, Image } from 'antd';
import { useEffect, useState } from 'react';
import { Uploder } from 'utils/helper';
import {
    ocrBankCardFirstFromOss,
    ocrBusinessLicenseFromOss,
    ocrIdCardFirstFromOss,
    ocrVehicleLicenseFirstFromOss,
    ocrVehicleRegistrationFromOss,
    ocrWeighingReceiptFromOss,
} from 'apis/common';

interface ImageUploadPops {
    value?: UploadFile[];
    onChange?: (files?: UploadFile[]) => void;
    onSuccess?: () => void;
    onOcrSuccess?: (data?: any) => void;
}

export type UploadFileType = UploadFile & {
    attachId?: string;
    filePath?: string;
};

const ImageUpload: React.FC<
    ImageUploadPops &
        UploadProps & {
            uploadText?: string;
            //  系统文件标识：1-系统文件 2-租户文件
            sysFileTag?: 1 | 2;
            ocrType?:
                | 'idCardFirstFromOss' // 身份证正面
                | 'idCardSecondFromOss' // 身份证背面
                | 'businessLicenseFromOss' // 营业执照
                | 'bankCardFirstFromOss' // 银行卡正面
                | 'weighingReceiptFromOss' // 过磅单
                | 'vehicleLicenseFirstFromOss-vehicleRegistrationFromOss' // 行驶证正面or机动车注册证书
                | 'vehicleLicenseFirstFromOss'; // 行驶证正面
        }
> = ({ uploadText, value, onChange, accept = 'image/*', sysFileTag = 2, ocrType, onOcrSuccess, ...rest }) => {
    const { message } = App.useApp();
    const [loading, setLoading] = useState(false);
    const isImageFile = (file: UploadFile) => {
        return file?.type?.startsWith('image/');
    };
    const [currentList, setCurrentList] = useState<UploadFile[]>(value || []);
    const beforeUpload = (file: UploadFile) => {
        const isImage = isImageFile(file);
        if (!isImage) {
            message.error(`${file.name}类型不是图片，请上传图片`);
        }
        return isImage || Upload.LIST_IGNORE;
    };
    const ocrFunc = async (attachId: string) => {
        if (ocrType) {
            switch (ocrType) {
                case 'idCardFirstFromOss': {
                    // 身份证正面
                    ocrIdCardFirstFromOss({
                        attachId,
                    })
                        .then((res) => {
                            onOcrSuccess?.(res);
                            message.success('识别成功');
                        })
                        .catch(() => {
                            message.error('识别失败');
                        });
                    break;
                }
                case 'businessLicenseFromOss': {
                    // 营业执照
                    ocrBusinessLicenseFromOss({
                        attachId,
                    })
                        .then((res) => {
                            onOcrSuccess?.(res);
                            message.success('识别成功');
                        })
                        .catch(() => {
                            message.error('识别失败');
                        });
                    break;
                }
                case 'bankCardFirstFromOss': {
                    // 银行卡
                    ocrBankCardFirstFromOss({
                        attachId,
                    })
                        .then((res) => {
                            onOcrSuccess?.(res);
                            message.success('识别成功');
                        })
                        .catch(() => {
                            message.error('识别失败');
                        });
                    break;
                }
                // 行驶证正面
                case 'vehicleLicenseFirstFromOss': {
                    ocrVehicleLicenseFirstFromOss({
                        attachId,
                    })
                        .then((res) => {
                            onOcrSuccess?.(res);
                            message.success('识别成功');
                        })
                        .catch(() => {
                            message.error('识别失败');
                        });
                    break;
                }
                // 过磅单
                case 'weighingReceiptFromOss': {
                    ocrWeighingReceiptFromOss({
                        attachId,
                    })
                        .then((res) => {
                            onOcrSuccess?.(res);
                            message.success('识别成功');
                        })
                        .catch(() => {
                            message.error('识别失败');
                        });
                    break;
                }
                // 行驶证正面or机动车注册证书
                case 'vehicleLicenseFirstFromOss-vehicleRegistrationFromOss': {
                    let success = false;
                    await ocrVehicleLicenseFirstFromOss({
                        attachId,
                    })
                        .then((res) => {
                            onOcrSuccess?.(res);
                            success = true;
                            // message.success('识别成功');
                        })
                        .catch(() => {
                            // message.error('识别失败');
                        });
                    if (success) {
                        message.success('识别成功');
                        break;
                    }
                    await ocrVehicleRegistrationFromOss({
                        attachId,
                    })
                        .then((res) => {
                            onOcrSuccess?.(res);
                            success = true;
                            // message.success('识别成功');
                        })
                        .catch(() => {
                            // message.error('识别失败');
                        });

                    if (success) message.success('识别成功');
                    else message.error('识别失败');
                    break;
                }
            }
        }
    };
    const customRequest: any = async ({
        file,
        onSuccess,
        onError,
    }: {
        file: UploadFileType;
        onSuccess: any;
        onError: any;
    }) => {
        setLoading(true);
        try {
            let { authQueryFileUrl, attachId, filePath } = await Uploder(file, sysFileTag);
            file.filePath = filePath;
            file.attachId = attachId;
            file.url = authQueryFileUrl;
            file.filePath = filePath;
            ocrFunc?.(attachId);
            onSuccess(file);
        } catch (error) {
            onError(new Error('上传失败'));
        } finally {
            setLoading(false);
        }
    };
    const onUploadChange: ({ file, fileList }: { file: UploadFile; fileList: UploadFile[] }) => void = ({
        file,
        fileList,
    }) => {
        setCurrentList(fileList);
        let uploadComplete = true;
        for (let i = 0; i < fileList.length; i++) {
            if (fileList[i].status === 'uploading') {
                uploadComplete = false;
                break;
            }
        }
        if (!uploadComplete) {
            return;
        }
        const list = fileList.filter((item) => item.status === 'done');
        onChange?.(list);
    };

    const [visible, setVisible] = useState(false);
    const [previewUrl, setPreviewUrl] = useState('');
    const onPreview = (file: UploadFile) => {
        if (file.url || file.thumbUrl) {
            setPreviewUrl(file.url || file.thumbUrl || '');
            setVisible(true);
        }
    };
    const uploadButton = (
        <Spin spinning={loading}>
            <button
                className={rest?.disabled ? 'ant-upload-disabled' : ''}
                style={
                    rest?.listType === 'text'
                        ? {
                              border: '1px solid #eee',
                              display: 'flex',
                              justifyItems: 'center',
                              alignItems: 'center',
                              padding: '4px 16px',
                          }
                        : { border: 0, background: 'none' }
                }
                type='button'
            >
                {!loading ? <Icon icon='ant-design:plus-outlined' /> : null}
                <div className={rest?.listType === 'text' ? 'mt-0' : 'mt-8px'}>{uploadText || '上传'}</div>
            </button>
        </Spin>
    );

    useEffect(() => {
        if (currentList?.length === 0) {
            setCurrentList(value || []);
        }
    }, [value]);
    return (
        <>
            <Upload
                fileList={currentList}
                onPreview={onPreview}
                accept={accept}
                listType='picture-card'
                beforeUpload={beforeUpload}
                customRequest={customRequest}
                onChange={onUploadChange}
                {...rest}
            >
                {(currentList?.length || 0) < (rest?.maxCount || 0) &&
                (!value || value?.length < (rest?.maxCount || 0)) &&
                !loading
                    ? uploadButton
                    : null}
            </Upload>
            {ocrType ? <div className='text-gray'>支持 OCR 自动识别相应字段并进行回填</div> : null}
            <Image
                width={200}
                style={{ display: 'none' }}
                src={previewUrl}
                preview={{
                    visible,
                    src: previewUrl,
                    onVisibleChange: (value) => {
                        setVisible(value);
                    },
                }}
            />
        </>
    );
};

export default ImageUpload;
